import { reactive } from 'vue';
import {defStoreKey, forEachValue} from "./utils";

export default class Store {
  constructor(options) {
    // 加一层data是为了方便后面更改state
    this._state = reactive({ data: options.state() });
    const _getters = options.getters;
    this.getters = {};
    forEachValue(_getters, (fn, key) => {
      // console.log(value, key);
      Object.defineProperty(this.getters, key, {
        // value: fn(this.state) 没有响应式
        get: () => fn(this.state)
      });
    });
    // Object.create是不带原型的空对象
    this._mutations = Object.create(null);
    this._actions = Object.create(null);


    const _mutations = options.mutations;
    const _actions = options.actions;
    forEachValue(_mutations, (mutationFn, key) => {
      this._mutations[key] = payload => {
        mutationFn.call(this, this.state, payload);
      }
    });
    forEachValue(_actions, (actionFn, key) => {
      this._actions[key] = payload => {
        actionFn.call(this, this, payload);
      }
    });
  }
  /*commit(type, payload) {
    // 如果用户在action里解构commit, { commit } this就是undefined
    console.log('commit this', this); // undefined
  }*/
  commit = (type, payload) => {
    this._mutations[type](payload);
  }
  dispatch(type, payload) {
    this._actions[type](payload);
  }
  get state() {
    return this._state.data;
  }
  install(app, injectKey = defStoreKey) {
    app.config.globalProperties.$store = this;
    app.provide(injectKey, this);
  }
}
